package whf.framework.util.var;

import whf.framework.log.Log;
import whf.framework.log.LogFactory;
import whf.framework.util.StringUtils;

/**
 * 变量解析工具
 * @author wanghaifeng
 * @create Jan 24, 2007 9:24:56 AM
 * 
 */
public class VariableUtils {
	private static Log log = LogFactory.getLog(VariableUtils.class);
	
	private static VariableInfo getVariableHolder(String variableKey){
		String[] keys = StringUtils.split(variableKey, ".");
		String holderName = keys[0];
		VariableHolder holder = VariableHolderFactory.getVairiableHolder(holderName);
		String variableName = "";
		for(int i=1; i< keys.length; i++){
			if(i > 1)
				variableName += ".";
			variableName += keys[i];
		}
		log.debug(holderName+":"+variableName);
		return new VariableInfo(holderName, variableName, holder);
	}
	
	/**
	 * 从变量容器中获取变量
	 * @modify wanghaifeng Jan 24, 2007 11:11:56 AM
	 * @param key
	 * @return
	 */
	public static Object getVariable(String key){
		if(StringUtils.isEmpty(key) || !key.startsWith("$")){
			throw new IllegalArgumentException("Invalid variable name!");
		}
		String name = key.substring(1);
		VariableInfo variableHolderInfo = getVariableHolder(name);
		if(variableHolderInfo != null){
			return variableHolderInfo.variableHolder.getVariable(variableHolderInfo.variableName);
		} else {
			return null;
		}
	}
	
	/**
	 * 解析字符串并使用变量定义的值替换字符串中的定义
	 * @param input
	 * @return
	 */
	public static String parseString(String input) {
		if(StringUtils.isEmpty(input)) return input;
		StringBuffer result = new StringBuffer(200);
		StringBuffer buff = new StringBuffer(20);
		for (int index = 0; index < input.length(); index++) {
			char c = input.charAt(index);
			if (c == '$') {
				if(buff.length() > 0){	// exists already
					Object value = getVariable(buff.toString());
					if(value != null){
						result.append(value.toString());
					}
				}
				buff.delete(0, buff.length());
				buff.append(c);
				continue;
			} else if(c >= 'A' && c <='Z' || c >='a' && c <= 'z' || c >='0' && c <= '9' || c == '.') {
				if(buff.length() > 0)
					buff.append(c);
				else
					result.append(c);
				continue;
			} else {
				if(buff.length() > 0){	// exists already
					Object value = getVariable(buff.toString());
					if(value != null){
						result.append(value.toString());
					}
					buff.delete(0, buff.length());
					result.append(buff);
				}
				result.append(c);
			}
		}
		if(buff.length() > 0){	// exists already
			Object value = getVariable(buff.toString());
			if(value != null){
				result.append(value.toString());
			}
			buff.delete(0, buff.length());
		}
		result.append(buff);
		return result.toString();
	}
	
	private static class VariableInfo{
		/**
		 * 解析后的holder名称
		 * @property String:holderName
		 */
		String holderName;
		
		/**
		 * 解析后的变量名称
		 * @property String:variableName
		 */
		String variableName;
		
		/**
		 * 容器
		 * @property VariableHolder:holder
		 */
		VariableHolder variableHolder;
		
		public VariableInfo(String holderName, String variableName, VariableHolder holder){
			this.holderName = holderName;
			this.variableName = variableName;
			this.variableHolder = holder;
		}
	}
	
	public static void main(String[] args) throws Exception{
		System.out.println(VariableUtils.getVariable("$datetime.now"));
		System.out.println(VariableUtils.getVariable("$datetime.year"));
		System.out.println(VariableUtils.getVariable("$datetime.month"));
		System.out.println(VariableUtils.getVariable("$datetime.day"));
		//
		System.out.println(VariableUtils.parseString("$datetime.now AAAA$datetime.month CCC$datetime.year"));
	}
}
